#!node
const fs = require('fs')
const path = require('path')

const char = {
    code(c, i = 0) { return typeof c === 'string' ? c.charCodeAt(i) : 0; },
    isdigit(c, i = 0) { const n = char.code(c, i); return n >= 48 && n <= 57; },
    islower(c, i = 0) { const n = char.code(c, i); return n >= 97 && n <= 122; },
    isupper(c, i = 0) { const n = char.code(c, i); return n >= 65 && n <= 90; },
    conv(c) {
        if (char.isupper(c)) {
            return '_' + c.toLowerCase();
        } else if (c === '!') {
            return '！';
        } else {
            return c;
        }
    }
}

/** @param {string} modref */
function modrefToPageLink(modref) {
    if (typeof modref !== 'string' || modref.length === 0) {
        return ''
    }
    return modref.split('_').map(s => {
        if (s.length === 0) {
            return ''
        }
        let r = s[0].toLowerCase()
        if (char.islower(s, 0)) {
            r = '_' + s[0]
        }
        for (let i = 1; i < s.length; i++) {
            r += char.conv(s[i]);
        }
        return r;
    }).join('__');
}

/** @param {string} d */
function parseHeader(d) {
    const ret = { title: '', modref: '' }
    // title
    const title = /^title\s*:\s*"(.*)"\s*$/mu.exec(d)
    if (title !== null) {
        ret.title = title[1]
    }
    // modref
    const modref = /^modref\s*:\s*"?(.*)"?\s*$/mu.exec(d)
    if (modref !== null) {
        ret.modref = modref[1]
    }
    return ret
}

/** @param {string} d */
function parseDetail(d) {
    return `
<details><summary>点击展开英文说明</summary>
${d.replace(/\{\{<\s+\/?[rm]\s+>\}\}/g, '')}
</details>
`
}

/** @param {string} d */
function parseBody(d) {
    let s = d.trim()

    s = s.replace(/(#+)\s*(\S+)\s*\{ \.modlist \}/g, "$1 $2") // remove `.modlist`

    const moddetail = /\{\{<\s+moddetail(\s*md="(.*)"\s*)?\s+>\}\}\n?/u.exec(s)
    if (moddetail !== null) {
        const index = moddetail.index
        const begin = moddetail[0].length + index
        const md = true
        if (moddetail.length > 1) {
            const md = moddetail[2] !== "false"
        }
        const endReg = /\{\{<\s+\/moddetail\s+>\}\}\n?/u.exec(s.substring(begin))
        if (endReg === null) {
            throw '[Body] moddtail end tag miss'
        }
        const end = endReg.index + begin
        const endOffset = endReg[0].length
        // console.log('[Body]  ', index, begin, '->', end, end + endOffset)
        s = s.substring(0, index - 1) +
            parseDetail(s.substring(begin, end - 1)) +
            s.substring(end + endOffset)
    }
    return s
}

/** @param {string} file */
function parseModPage(file) {
    try {
        const fn = path.join('./content/mods', file)
        if (!fs.statSync(fn).isFile()) {
            return null
        }
        const d = fs.readFileSync(fn, { encoding: 'utf8' }).replace(/\r\n/g, '\n')

        // begin parsing
        const headerBegin = d.indexOf("---\n");
        if (headerBegin < 0) {
            throw '[Header] begin "---" not found'
        }
        const headerEnd = d.indexOf("---\n", headerBegin + 4);
        if (headerEnd < 0) {
            throw '[Header] end "---" not found'
        }
        // console.log('[Header]', headerBegin, '-', headerEnd)
        let ret = parseHeader(d.substring(headerBegin + 4, headerEnd - 1))

        // moddetail
        const bodyBegin = headerEnd + 4
        ret.desc = parseBody(d.substring(bodyBegin))

        // check file and modref
        const ref = modrefToPageLink(ret.modref)
        const fileRawname = file.replace(/\.md$/, '')
        if (fileRawname !== ref) {
            console.warn(`[Link] file '${fileRawname}' should be '${ref}' <- '${ret.modref}'`)
        }

        return ret
    }
    catch (e) {
        console.error(e, '@', file)
        return null
    }
}

function generateModInfo() {
    const files = fs.readdirSync('./content/mods')
    let ret = ''
    let stat = {
        count: 0,
        all: 0,
        check: 0,
        logs: fs.readdirSync('./logs').length,
    }
    for (const fname of files) {
        const res = parseModPage(fname)
        if (res === null) {
            continue
        }
        ret += `\
[[mods]]
file = "${fname}"
modref = "${res.modref}"
title = "${res.title}"
desc = """
${res.desc}\
"""
`
        stat.count++
    }

    const list = fs.readFileSync('./content/home/modlist.md', { encoding: 'utf8' })
    for (let i = 0; i < list.length; i++) {
        switch (list[i]) {
            case "✅":
                stat.check++
                stat.all++
                break;
            case "🔜":
                stat.all++
                break
            default:
                break
        }
    }

    console.log('stat', stat)
    ret += `
[stat]
all = ${stat.all}
check = ${stat.check}
count = ${stat.count}
logs = ${stat.logs}
`
    return ret
}

function main(argv) {
    info = generateModInfo()
    fs.writeFileSync('./mods.toml', info)
}

main(process.argv)